home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 134_01.zip / CTOA2.C < prev    next >
Text File  |  1993-06-12  |  11KB  |  443 lines

  1. /*    CTOA2.C: CRL-to-CSM file postprocessor, part 2.    */
  2.  
  3. #include <bdscio.h>
  4. #include <dio.h>
  5. #include <cmdutil.h>
  6. #include "ctoatbls.h"
  7. #include "ctoa.h"
  8.  
  9. /*    Acquire the C.CCC symbol table, and put any non-library-defined
  10.     symbols on the .CSM file.    */
  11.  
  12. initccc () {
  13.     struct ccc_entry * ccc;
  14.  
  15.     ccc_table = ccctabl ();
  16.  
  17.     for (ccc=ccc_table; ccc -> ccc_addr; ++ccc) {
  18.         if (ccc -> ccc_flags & CCC_NMAC) {
  19.             printf ("%s:\tequ\t0%04xH\t\t; C.CCC entry point\n",
  20.                 ccc->ccc_name, ccc->ccc_addr);
  21.             }
  22.         }
  23.     printf ("\n");
  24.     }
  25.  
  26. /*    Find a symbol in the C.CCC symbol table with the requisite attributes*/
  27.  
  28. struct ccc_entry * scanccc (addr, flags)
  29.     unsigned addr;        /* Address to look for */
  30.     char flags;            /* Flags required */
  31.     {
  32.     struct ccc_entry * ccc;
  33.  
  34.     for (ccc = ccc_table; ccc -> ccc_addr; ++ccc)
  35.         if ((ccc -> ccc_flags & flags) == flags
  36.          && ccc -> ccc_addr == addr) 
  37.             return (ccc);
  38.     return (NULL);
  39.     }
  40.  
  41. /*    Display an address from the C.CCC symbol table */
  42.  
  43. putccc (ccc)
  44.     struct ccc_entry * ccc;
  45.     {
  46.     printf ("%s", ccc -> ccc_name);
  47.     }
  48.  
  49. /*    Locate a function on the source file.  Function is presumed to
  50.     start when its name appears outside curly-braces. */
  51.  
  52. sfunct (s)
  53.     char * s;                /* Function name */
  54.     {
  55.     do {
  56.         if (seof) return;    /* End of file; no hope. */
  57.         sscan();        /* Look for the name. */
  58.         } while (slevel != 0 || strcmp (sname, s));
  59.     infunct = TRUE;
  60.     sline = 1;            /* This is first line of function. */
  61.     while (slevel == 0 && !seof) sscan ();    /* Find the open brace */
  62.     seol ();            /* Advance to a line break. */
  63.     }
  64.  
  65. /*    Advance to the end of a function by balancing curly-braces. */
  66.  
  67. sendfn () {
  68.     infunct = FALSE;
  69.     while (slevel > 0 && !seof) sscan ();    /* Eat tokens 'til balanced. */
  70.     seol ();            /* Advance to a line break. */
  71.     }
  72.  
  73. /*    Locate a line within the current function. */
  74.  
  75. slineno (l)
  76.     int l;                /* Line number to find. */
  77.     {
  78.     while (sline != 0 && sline <= l) {    /* Advance */    
  79.         sscan ();
  80.         seol ();
  81.         }
  82.     }
  83.  
  84. /*    Advance source file to a line break    */
  85.  
  86. seol () {
  87.     while (slopen) sscan ();
  88.     }
  89.  
  90. /*    Scan a token out of the source file    */
  91.  
  92. sscan () {
  93.     int c;            /* Current character from file */
  94.  
  95.     c = getc (srcfile);    /* Get a character */
  96.     if (isalpha (c) || c == '_') 
  97.         ssymb (c);    /* Scan an identifier if that's what we have */
  98.     else {
  99.         sputc (c);    /* Flush the current character to output */
  100.         switch (c) {
  101. case '/':        scomt ();        /* Process comments */
  102.             break;
  103. case '{':        ++slevel;        /* Balance curly braces */
  104.             break;
  105. case '}':        --slevel; /* NO BREAK HERE */
  106. case ';':        if (!infunct) sline = 0;    /* Reset relative line
  107.                             when leaving function*/
  108.             break;
  109. case '\'':
  110. case '"':        squote (c);        /* Process quoted strings */
  111.             break;
  112. case '\n':        if (sline) ++sline;    /* Maintain relative line # */
  113.             break;
  114. case CPMEOF:
  115. case EOF:        seof = TRUE;        /* Handle EOF */
  116.             slopen = FALSE;
  117.             sline = 0;
  118.             break;
  119.             }
  120.         }
  121.     }
  122.  
  123. /*    Read an identifier from source file     */
  124.  
  125. ssymb (c)
  126.     int c;
  127.     {
  128.     char * symp;            /* Pointer to symbol being scanned */
  129.     
  130.     symp = & sname;            /* Initialize scan pointer */
  131.  
  132.     do {
  133.         if (slevel == 0) *symp++ = toupper (c);    
  134.                         /* Accumulate character */
  135.         sputc (c);
  136.         c = getc (srcfile);        /* Get next character */
  137.         } while (isalpha(c) || isdigit (c) || c == '_');
  138.     ungetc (c, srcfile);        /* Push back char that stopped scan */
  139.     if (slevel == 0) *symp++ = '\0';    /* End the symbol */
  140.     sname [8] = '\0';        /* Truncate it to 8 bytes */
  141.     }
  142.  
  143. /*    Read a quoted string from source file     */
  144.  
  145. squote (c)
  146.     int c;
  147.     {
  148.     int c2;
  149.     c2 = c;
  150.     do {
  151.         if (c2 == '\\') sputc (getc (srcfile));    /* Do escapes */
  152.         c2 = sputc (getc (srcfile));    /* Next char */
  153.         } while (c2 != c && c2 != CPMEOF && c2 != EOF);
  154.     }
  155.  
  156. /*    Read a 'C' comment from source file     */
  157.  
  158. scomt () {
  159.     int c;
  160.     if ((c = getc (srcfile)) != '*') {    /* Really a comment? */
  161.         ungetc (c, srcfile);        /* No, put it back */
  162.         return;
  163.         }
  164.     sputc (c);
  165.     do {
  166.         while ((c = sputc (getc (srcfile))) != '*') { /* Find '*' */
  167.             if (c == EOF || c == CPMEOF) return;
  168.             if (c == '/') scomt ();    /* Handle nested comments */
  169.             }
  170.         if ((c = getc (srcfile)) == '*')     /* Handle ... ***/
  171.             ungetc (c, srcfile);
  172.         else sputc (c);
  173.         } while (c != '/' && c != EOF && c != CPMEOF);
  174.     }
  175.  
  176. /*    Copy a source character to the .CSM file    */
  177.  
  178. int sputc (c)
  179.     int c;
  180.     {
  181.     if (!slopen) {            /* Begin a new comment line */
  182.         printf ("; ");
  183.         slopen = TRUE;
  184.         }
  185.     if (c != EOF && c != CPMEOF)
  186.         printf ("%c", c);    /* Put the character */
  187.     if (c == '!') printf (";");    /* Keep ASM from barfing. */
  188.     else if (c == '\n') slopen = FALSE;    /* Close source line */
  189.     return (c);
  190.     }
  191.  
  192. /*    Open the .CDB file, and set up .CDB processing.    */
  193.  
  194. int initcdb () {
  195.     int cdblen;        /* Length of the file in bytes */
  196.     
  197.     nextvs = nautvs = nparvs = 0;    /* No variables read yet */
  198.  
  199.     strcpy (cdbfnam, srcfnam);        /* Get CDB name */
  200.     makeext (cdbfnam, "CDB");
  201.     if (copen (cdbfile, cdbfnam) == ERROR) { /* Open CDB file */
  202.         fprintf (STD_ERR,
  203.           "; Can't open %s: %s.\n; Assume %s compiled without '-k'.\n",
  204.             cdbfnam, errmsg (errno ()), srcfnam);
  205.         havecdb = cdbopen = FALSE;
  206.         return;
  207.         }
  208.     havecdb = cdbopen = TRUE;
  209.  
  210.     tcseek (cdbfile, 0, CABS, cdbfnam);    /* Read CDB length */
  211.     tcread (cdbfile, &cdblen, 2, cdbfnam);
  212.     ncdbents = cdblen / sizeof cdbentry;
  213.     
  214.     get1cdbe ();            /* Read first CDB entry */
  215.     }
  216.  
  217. /*    Read the definitions for one function from the .CDB file */
  218.  
  219. cdbfunct () {
  220.     int level;            /* "Block level" from CDB entry */
  221.     char gotfunct;            /* Flag = TRUE iff we've found start
  222.                        of function's lexical scope on CDB*/
  223.  
  224.     ++fnno;                /* Count functions */
  225.     nparvs = nautvs = 0;        /* No params or autos yet. */
  226.     gotfunct = FALSE;        /* Haven't seen funct. yet. */
  227.     while (cdbopen) {
  228.         if ((level = cdbentry.cdbflag2 & 0x3F) == 0
  229.          && (cdbentry.cdbflag1 & 0x0F) == 0x01) { /* Funct def? */
  230.             if (gotfunct) break;
  231.             framesize = cdbentry . cdbaddr;
  232.             gotfunct = TRUE;
  233.             }
  234.         else if (level == 0) { /* External? */
  235.             if (gotfunct) break;
  236.             cdbext ();
  237.             }
  238.         else if (level == fnno)                 /* Auto? */
  239.             cdbauto ();
  240.         get1cdbe ();        /* Read next CDB entry */
  241.         }
  242.     }
  243.  
  244. /*    Process an external variable from .CDB    */
  245.  
  246. cdbext () {
  247.     if (!(cdbentry.cdbflag1 & 0x0F)) {    /* Really an external var? */
  248.         strcpy70 (extvtab [nextvs] . vtname, cdbentry . cdbname);
  249.         extvtab [nextvs] . vtaddr = cdbentry . cdbaddr;
  250.         printf ("EXT$%s\tEQU\t%05xh\n", extvtab [nextvs] . vtname,
  251.             extvtab [nextvs] . vtaddr);
  252.         ++nextvs;
  253.         }
  254.     }
  255.  
  256. /*    Process an auto or parameter variable from CDB    */
  257.  
  258. cdbauto () {
  259.     if (!(cdbentry . cdbflag1 & 0x0F)) {    /* Really an auto? */
  260.         strcpy70 (autvtab [nautvs] . vtname, cdbentry . cdbname);
  261.         autvtab [nautvs++] . vtaddr = cdbentry . cdbaddr;
  262.         }
  263.     else if (!(cdbentry . cdbflag1 & 0x0B)) { /* How about a parameter? */
  264.         strcpy70 (parvtab [nparvs] . vtname, cdbentry . cdbname);
  265.         parvtab [nparvs++] . vtaddr = cdbentry . cdbaddr;
  266.         }
  267.     }
  268.  
  269. /*    Read a variable description from the .CDB file     */
  270.  
  271. get1cdbe () {
  272.     if (--ncdbents < 0) {
  273.         cdbopen = FALSE;
  274.         cclose (cdbfile);
  275.         }
  276.     else {
  277.         tcread (cdbfile, cdbentry, sizeof cdbentry, cdbfnam);
  278.         }
  279.     }
  280.  
  281. /*    Output the stack frame layout of a function    */
  282.  
  283. doframe () {
  284.     int i;
  285.     
  286.     for (i=0; i<nautvs; ++i)
  287.         printf ("AUTO$%s\tSET\t%05xh\n", autvtab [i] . vtname,
  288.             autvtab [i] . vtaddr);
  289.     printf ("\nFRAME$SIZE\tSET\t%05xh\n\n", framesize);
  290.     for (i=0; i<nparvs; ++i)
  291.         printf ("PARAM$%s\tSET\t%05xh\n", parvtab [i] .vtname,
  292.             parvtab [i] . vtaddr);
  293.     printf ("\n");
  294.     }
  295.  
  296. /*    Output a stack pointer increment/decrement     */
  297.  
  298. do_frsiz (adder)
  299.     int adder;
  300.     {
  301.     if (!havecdb || abs (adder) != framesize) {
  302.         printf ("%05xh\t\t; %d", adder, adder);
  303.         return;
  304.         }
  305.     if (adder < 0) printf ("-");
  306.     printf ("FRAME$SIZE");
  307.     }
  308.     
  309. /*    Output an offset into automatic storage        */
  310.  
  311. do_autoff (offset)
  312.     unsigned offset;
  313.     {
  314.     if (!havecdb) {
  315.         printf ("%05xh\t\t; %d", offset, offset);
  316.         return;
  317.         }
  318.     if (offset >= framesize+4) {    /* Really a parameter? */
  319.         printf ("FRAME$SIZE+4+PARAM$");
  320.         do_offset (nparvs, parvtab, offset-framesize-4);
  321.         }
  322.     else {                       /* No, really AUTO */
  323.         printf ("AUTO$");
  324.         do_offset (nautvs, autvtab, offset);
  325.         }
  326.     }
  327.  
  328. /*    Output an offset into external storage     */
  329.  
  330. do_extoff (offset)
  331.     unsigned offset;
  332.     {
  333.     if (!havecdb) {
  334.         printf ("%05xh\t\t; %d", offset, offset);
  335.         return;
  336.         }
  337.     printf ("EXT$");
  338.     do_offset (nextvs, extvtab, offset);
  339.     }
  340.  
  341. /*    Output an offset relative to a particular variable table */
  342.  
  343. do_offset (nvars, vartab, offset)
  344.     int nvars;
  345.     struct vtabent *vartab;
  346.     unsigned offset;
  347.     {
  348.     while (--nvars >= 0) {
  349.         if (vartab [nvars] . vtaddr <= offset) {
  350.             printf ("%s", vartab [nvars] . vtname);
  351.             offset -= vartab [nvars] . vtaddr;
  352.             break;
  353.             }
  354.         }
  355.     if (offset) printf ("+%d", offset);
  356.     }
  357.  
  358. /*    Put an extension on a file name    */
  359.  
  360. makeext (name, ext)
  361.     char * name;        /* Name of the file */
  362.     char * ext;            /* Desired extension */
  363.     {
  364.     do {            /* Find the separatrix */
  365.         if (!*name) {    /* No extension originally */
  366.             *name++ = '.';
  367.             break;
  368.             }
  369.         } while (*name++ != '.');
  370.  
  371.     strcpy (name, ext);    /* Add the extension */
  372.     return (name);
  373.     }
  374.  
  375. /*    Copy a bit-7-terminated string to a null-terminated one. */
  376.  
  377. strcpy70 (out, in)
  378.     char * out;            /* Null-terminated string output */
  379.     char * in;            /* Bit-7-terminated string in */
  380.     {
  381.     char * tout;
  382.     tout = out;
  383.  
  384.     do {
  385.         *tout++ = *in & 0x7f;    /* Move a character */
  386.         } while ((*in++ & 0x80) == 0);    /* Until end mark reached */
  387.     *tout++ = '\0';        /* Supply the end marker on output */
  388.     return (out);        /* Return the output string */
  389.     }
  390.  
  391. /*    Error-checking equivalents of the "CHARIO" functions    */
  392.  
  393. tcopen (buf, name)
  394.     CFILE * buf;        /* File to be opened */
  395.     char * name;        /* Name to open it with */
  396.     {
  397.     int retval;
  398.     if ((retval = copen (buf, name)) == ERROR) {
  399.         fprintf (STD_ERR, "Unable to open %s: %s\n",
  400.                         name, errmsg (errno ()));
  401.         quit ();
  402.         }
  403.     return (retval);
  404.     }
  405.  
  406. tcseek (buf, addr, type, name)
  407.     CFILE * buf;        /* File on which to seek */
  408.     unsigned addr;        /* Address being sought */
  409.     int type;            /* Type of seek (absolute/relative) */
  410.     char * name;        /* Filename for error message */
  411.     {
  412.     int retval;
  413.     if ((retval = cseek (buf, addr, type)) == ERROR) {
  414.         fprintf (STD_ERR, "Seek error on %s: %s\n",
  415.                         name, errmsg (errno ()));
  416.         quit ();
  417.         }
  418.     return (retval);
  419.     }
  420.  
  421. tcread (buf, loc, len, name)
  422.     CFILE * buf;        /* File to read */
  423.     char * loc;            /* Place to put the result */
  424.     unsigned len;        /* Number of bytes to read */
  425.     char * name;        /* Filename for error message */
  426.     {
  427.     int retval;
  428.     if ((retval = cread (buf, loc, len)) == ERROR) {
  429.         fprintf (STD_ERR, "Read error on %s: %s\n",
  430.                         name, errmsg (errno ()));
  431.         quit ();
  432.         }
  433.     return (retval);
  434.     }
  435.  
  436. /*    Stop the program prematurely    */
  437.  
  438. quit () {
  439.     dioflush ();
  440.     exit ();
  441.     }
  442.  
  443.